<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width">
        <meta name="restype" content="documentation">
        <meta name="product" content="kendo-ui">
        <meta name="subproduct" content="listview_mobile">
        <title>Endless Scrolling | Hybrid UI ListView</title>
        <link rel="shortcut icon" href="/favicon.ico"/>
        <meta name="description" content="Use the endless scrolling feature of the Hybrid UI ListView in the Kendo UI framework.">
        <link href="//fonts.googleapis.com/css?family=Roboto:400,500,700,900" rel="stylesheet">
        <link href='https://fonts.googleapis.com/css?family=Roboto+Mono:400,500,700' rel='stylesheet' type='text/css'>
        <!-- <link href="https://kendo.cdn.telerik.com/2017.3.1026/styles/kendo.common.min.css" rel="stylesheet" /> -->
        <link rel="stylesheet" href="http://oygy5legq.bkt.clouddn.com/kendo.common.min.css">
        <link rel="stylesheet" href="/assets/styles.css?cb=8338967476da1c756a6defe19c1f9984">
        <link rel="stylesheet" href="/assets/icon-font.css?cb=25d8b9593057297c278fcd6d7d263c8e">
        <link rel="stylesheet" href="/assets/theme.css?cb=d82da02940126146560da1ae3bb0bf64">
        
        <!-- <script src="https://code.jquery.com/jquery-1.10.2.js"></script> -->
        <script src="https://cdn.bootcss.com/jquery/1.10.2/jquery.min.js"></script>
        <!-- <script src="https://kendo.cdn.telerik.com/2017.3.1026/js/kendo.web.min.js"></script> -->
        <script src="http://oygy5legq.bkt.clouddn.com/kendo.web.min.js"></script>
        <!-- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.6.0/codemirror.min.css">
        <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.6.0/codemirror.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.6.0/mode/javascript/javascript.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.6.0/mode/css/css.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.6.0/mode/xml/xml.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.6.0/mode/htmlmixed/htmlmixed.min.js"></script> -->
        <script src="/assets/prettify.js?cb=9671553084e1962263b152af1f563c3c"></script>
        <script src="/assets/app.js?cb=c577f29da14c3752a8c4ba001dde39e5"></script>
        
        

        <!--[if lt IE 9]>
        <script>
        document.createElement('header');
        document.createElement('nav');
        document.createElement('section');
        document.createElement('article');
        document.createElement('aside');
        document.createElement('footer');
        document.createElement('hgroup');
        </script>
        <![endif]-->
    </head>
    <body>
        <!-- Google Tag Manager -->
        <!-- <noscript>
            <iframe src="//www.googletagmanager.com/ns.html?id=GTM-6X92" height="0" width="0" style="display: none; visibility: hidden"></iframe>
        </noscript>
        <script>(function(w, d, s, l, i) { w[l] = w[l] || []; w[l].push({ 'gtm.start': new Date().getTime(), event: 'gtm.js' }); var f = d.getElementsByTagName(s)[0], j = d.createElement(s), dl = l != 'dataLayer' ? '&l=' + l : ''; j.async = true; j.src = '//www.googletagmanager.com/gtm.js?id=' + i + dl; f.parentNode.insertBefore(j, f); })(window, document, 'script', 'dataLayer', 'GTM-6X92');</script> -->
        <!-- End Google Tag Manager -->
        <aside class="TK-Hat">
    <figure class="TK-Hat-Brand">
        <a href="https://www.progress.com" class="TK-PRGS-Logo">
            <svg xmlns="http://www.w3.org/2000/svg" width="94" height="40" viewBox="0 0 512 120">
                <path fill="#5ce500" d="M95.52 29.33v51a3.93 3.93 0 0 1-1.78 3.08l-1.67 1-12.72 7.35-8.59 5-1.78 1V42.6L21.23 15 43.91 1.93 46 .74a3.94 3.94 0 0 1 3.56 0L81 18.9l14.51 8.38v2.05zM58.36 48.72l-9.79-5.66-22.91-13.23a4 4 0 0 0-3.56 0L1.77 41.57 0 42.6l34.49 19.91v39.83l20.3-11.73 1.79-1a3.94 3.94 0 0 0 1.78-3.08V48.72zM0 82.43l23.86 13.78V68.63z"></path>
                <path fill="#4b4e52" d="M148.09 27.28h-26v70.48h11.55V70.1h14.57c15.77 0 24.45-7.7 24.45-21.69 0-6.35-2.4-21.12-24.55-21.12m12.78 21.31c0 7.95-4.12 11.19-14.24 11.19h-13v-22.1h14.57c8.56 0 12.71 3.57 12.71 10.91M207 46.41l.87.42-2 10.42-1.35-.42a11.32 11.32 0 0 0-3.34-.51c-10.79 0-11.67 8.59-11.67 19v22.44h-10.64V46h10v6.24c2.73-4.2 6-6.37 10.37-6.9a14.55 14.55 0 0 1 7.76 1.07M233.29 45c-8.42 0-15.16 3.2-19.5 9.27-4.56 6.37-5.23 13.85-5.23 17.74 0 16.36 9.7 26.92 24.73 26.92 18.26 0 24.73-14.71 24.73-27.3 0-7.25-2.15-13.82-6-18.51-4.41-5.31-10.87-8.12-18.7-8.12m0 44.38c-8.37 0-13.57-6.66-13.57-17.37s5.2-17.55 13.57-17.55S247 61.23 247 71.78c0 10.83-5.24 17.56-13.66 17.56m114.55-42.93l.87.42-2 10.42-1.35-.42a11.26 11.26 0 0 0-3.33-.51c-10.78 0-11.66 8.59-11.66 19v22.44h-10.66V46h10v6.24c2.73-4.2 6-6.37 10.37-6.9a14.54 14.54 0 0 1 7.73 1.06m38.4 34.76l-.2.57c-2.23 6.36-7.57 7.7-11.65 7.7-8.09 0-13.3-5.37-13.81-14.09h36.59l.13-1a31.26 31.26 0 0 0 .12-4.12v-.93C396.93 54.78 387.48 45 374 45c-7.9 0-14.37 3.1-18.73 9a30.85 30.85 0 0 0-5.54 18c0 16 9.95 26.74 24.74 26.74 11.45 0 19.33-5.82 22.2-16.38l.33-1.2h-10.7zM361 66.05c.9-7.17 5.81-11.73 12.79-11.73 5.33 0 11.64 3.1 12.52 11.73H361zm-60.7-15.71c-3.45-3.58-8.06-5.39-13.76-5.39-15.69 0-22.83 13.81-22.83 26.63 0 13.16 7.06 26.44 22.83 26.44a18.33 18.33 0 0 0 13.35-5.42c0 2.28-.1 4.45-.16 5.38-.58 8.54-4.68 12.51-12.91 12.51-4.47 0-9.61-1.59-10.6-6l-.22-1h-10.54l.17 1.41c1.1 9.12 9.11 14.79 20.9 14.79 10.34 0 17.7-3.9 21.28-11.26 1.73-3.55 2.6-8.72 2.6-15.37V46h-10.13v4.34zm-13.11 38.15c-3.74 0-12.43-1.69-12.43-17.37 0-10.3 4.87-16.7 12.71-16.7 6.06 0 12.52 4.39 12.52 16.7 0 10.87-4.79 17.37-12.81 17.37m159.67-6.31c0 8.23-6.83 16.53-22.09 16.53-13.5 0-21.53-5.85-22.61-16.45l-.15-1.1h10.52l.21.84c1.29 6.38 7.37 7.72 12.24 7.72 5.34 0 11-1.72 11-6.54 0-2.44-1.59-4.18-4.73-5.16-1.86-.55-4.15-1.2-6.56-1.87-4.16-1.16-8.47-2.38-11.12-3.29-6.56-2.35-10.33-6.93-10.33-12.56 0-10.43 10.16-15.11 20.22-15.11 13.46 0 20.42 5.07 21.3 15.49l.09 1.07H434.5l-.14-.82c-1-6-7-6.9-10.48-6.9-3 0-10 .53-10 5.5 0 2.25 1.93 3.91 5.89 5.06 1.18.33 2.94.78 5 1.31 4.22 1.09 9.48 2.46 12.13 3.37 6.59 2.32 9.93 6.67 9.93 13m49.39 0c0 8.23-6.83 16.53-22.09 16.53-13.5 0-21.53-5.85-22.61-16.45l-.11-1.09H462l.12.74c1.29 6.38 7.37 7.72 12.24 7.72 5.34 0 11-1.72 11-6.54 0-2.44-1.59-4.18-4.72-5.16-1.86-.55-4.15-1.2-6.57-1.87-4.16-1.16-8.46-2.38-11.11-3.29-6.57-2.35-10.33-6.93-10.33-12.56 0-10.43 10.16-15.11 20.22-15.11 13.46 0 20.42 5.07 21.29 15.49l.09 1.07H483.9l-.14-.82c-1-6-7-6.9-10.48-6.9-3 0-9.95.53-9.95 5.5 0 2.25 1.93 3.91 5.89 5.06 1.18.33 2.94.78 5 1.31 4.22 1.09 9.48 2.46 12.13 3.37 6.58 2.32 9.93 6.67 9.93 13m8.43-30.78a7.37 7.37 0 1 1 7.29-7.37 7.23 7.23 0 0 1-7.29 7.37m0-13.49a6.12 6.12 0 1 0 6 6.12 5.91 5.91 0 0 0-6-6.12m-.85 7.49v2.46h-2.17v-7.74h3.62a2.58 2.58 0 0 1 2.86 2.7 2.26 2.26 0 0 1-1.49 2.34l1.77 2.7H506l-1.49-2.46h-.68zm1.21-3.49h-1.21v1.73h1.21a.86.86 0 0 0 1-.85.88.88 0 0 0-1-.89"></path>
            </svg>
        </a>
    </figure>
</aside>
<header id="page-header">
    <div class="toggle-nav"><span class="k-icon k-i-menu"></span></div>


    <div id="logo-bar">
        <a href="/introduction">
            <img alt="Kendo UI logo" class="logo" src="/images/kendo-ui.svg">
        </a>
    </div>

    
    <span class="show-search">
        <span class="k-icon k-i-search"></span>
    </span>
    
    <div class="nav-buttons">
        <a href="http://demos.telerik.com/kendo-ui/" class="btn demos-btn">Demos</a>
        <a href="http://www.telerik.com/kendo-ui" class="btn about-btn">About</a>
        <a href="http://www.telerik.com/purchase/kendo-ui" class="btn pricing-btn">Pricing</a>
        <a href="http://www.telerik.com/download/kendo-ui" class="btn btn-primary">Try now</a>
    </div>
</header>
        <div id="page-inner-content">
    <div id="page-nav">
        <div id="page-tree"></div>
        <script>
        $("#page-tree").kendoTreeView({
            dataSource: {
                transport: {
                    read: {
                        url: "/default.json",
                        dataType: "json"
                    }
                },
                schema: {
                    model: {
                        id: "path",
                        children: "items",
                        hasChildren: "items"
                    }
                }
            },
            messages: {
                loading: " "
            },
            select: preventParentSelection,
            template: navigationTemplate("/"),
            dataBound: expandNavigation("controls/hybrid/listview/endless-scrolling.html")
        });
        </script>
    </div>

    <a id="page-edit-link" href="https://github.com/telerik/kendo-ui-core/edit/master/docs//controls/hybrid/listview/endless-scrolling.md"><span class="k-icon k-i-pencil"></span> Edit this page</a>
    

    <div id="page-article">
        <article>
            
             <h1 id="endless-scrolling"><a href="#endless-scrolling">Endless Scrolling</a></h1>

<p>The <a href="http://demos.telerik.com/kendo-ui/m/index#mobile-listview/index">Hybrid UI ListView widget</a> supports displaying large amounts of data by appending additional pages of data on demand. Loading can happen automatically by enabling the <a href="/api/mobile/listview#configuration-endlessScroll">endless scrolling functionality</a>, or by displaying a button at the bottom (<a href="/api/mobile/listview#configuration-loadMore"> press to load more </a>).</p>

<h2 id="virtual-mode"><a href="#virtual-mode">Virtual Mode</a></h2>

<p>Enabling endless scrolling or pressing to load more options trigger the virtual mode of the ListView. In order for the ListView virtual mode to be working as expected, the ListView should be the only widget in the scrolling container. If more widgets are needed in the view in question, the ListView should be wrapped in a mobile scroller container.</p>

<p>The virtual mode interacts and alters the behavior of the containing scroller widget—by default, the view scroller. Native scrolling—a view with the <code>use-native-scrolling=true</code>, or scroller with the <code>use-native=true</code> attribute—is not supported.</p>

<p>In virtual mode, a fixed amount of DOM elements is rendered, and then dynamically repositioned and updated when the user scrolls the view. In the endless scrolling mode, the next page is automatically pre-fetched when the user scrolls past two thirds of the current set of items.</p>

<blockquote>
<p><strong>Important</strong></p>

<p>The amount of actual DOM elements used in virtual mode is equal to half of the datasource page size option.</p>
</blockquote>

<p>In order for the scrolling to occur smoothly, the page size should not be too low. For example, if five items are visible on the page, at least fifteen physical DOM elements are needed, which means that the DataSource page size should be thirty or more.</p>

<blockquote>
<p>Bigger DataSource page size ensures smooth scrolling, but has adverse effects on view transition performance.</p>
</blockquote>

<p>Once the ListView reaches the amount of items specified by the <a href="/api/framework/datasource#configuration-schema.total">schema.total</a> setting of the datasource, the <strong>Load More</strong> button/endless scrolling indicator is hidden.</p>

<blockquote>
<p><strong>Important</strong></p>

<ul>
<li>Currently, certain features, such as the grouped mode and inset styling, are not supported in virtual mode.</li>
<li>If the total number of items is changed after editing, call the <a href="/api/framework/datasource#methods-read"><code>read</code></a> method of the DataSource.</li>
</ul>
</blockquote>

<h2 id="getting-started"><a href="#getting-started">Getting Started</a></h2>

<h3 id="create-listviews-with-endless-scrolling"><a href="#create-listviews-with-endless-scrolling">Create ListViews with Endless Scrolling</a></h3>

<p>First, decide what the best way to get the additional data is. The possible ways to do this are:</p>

<ul>
<li>
<code>local</code>—The whole data is serialized on the client. As the user scrolls down, new data is displayed.</li>
<li>
<code>remote</code>—Only the first page of the data is serialized and rendered on the client. When the user reaches the end of the list, an Ajax request is made to fetch the next portion of the data.</li>
</ul>

<h2 id="data-binding"><a href="#data-binding">Data Binding</a></h2>

<h3 id="bind-to-local-arrays"><a href="#bind-to-local-arrays">Bind to Local Arrays</a></h3>

<p><strong>Step 1</strong> Define a target HTML element such as a list.</p>

<h6>Example</h6>

<pre><code>&lt;ul id="localListView"&gt;&lt;/ul&gt;
</code></pre>

<p><strong>Step 2</strong> Define a function, which will return a list of generated data, as demonstrated in the example below.</p>

<h6>Example</h6>

<pre><code>    //generate local data
    function getData() {
        var data = [], idx = 0;
        for (; idx &lt; 1000; idx++) {
            data.push({
                name: "Name" + idx
            });
        }

        return data;
    }
</code></pre>

<p><strong>Step 3</strong> Create a DataSource instance. Note that the <code>pageSize</code> is required.</p>

<h6>Example</h6>

<pre><code>    //define the DataSource
    var dataSource = new kendo.data.DataSource({ data: getData() });
</code></pre>

<p><strong>Step 4</strong> Initialize the ListView.</p>

<h6>Example</h6>

<pre><code>    //initialize the Mobile ListView
    $("#listView").kendoMobileListView({
        dataSource: dataSource,
        template: "#: name #",

        endlessScroll: true,
        virtualViewSize: 50 // needed setting, since local data virtualization does not use paging
    });
</code></pre>

<p>This is the live example of the representation above:</p>

<pre data-lang="html"><code>&lt;div data-role="view" data-layout="default" data-init="viewInit"&gt;
  &lt;ul id="listView"&gt;&lt;/ul&gt;
&lt;/div&gt;

&lt;section data-role="layout" data-id="default"&gt;
  &lt;header data-role="header"&gt;
    &lt;div data-role="navbar"&gt;My App&lt;/div&gt;
  &lt;/header&gt;
&lt;/section&gt;

&lt;script&gt;
  function getData() {
    var data = [], idx = 0;

    for (; idx &lt; 1000; idx++) {
      data.push({
        name: "Name" + idx
      });
    }

    return data;
  }

  var dataSource = new kendo.data.DataSource({
    data: getData()
  });

  function viewInit() {
    $("#listView").kendoMobileListView({
      dataSource: dataSource,
      template: "#: name #",
      endlessScroll: true, 
      virtualViewSize: 50
    });
  }

  var app = new kendo.mobile.Application(document.body);
&lt;/script&gt;
</code></pre>

<h3 id="bind-to-remote-data"><a href="#bind-to-remote-data">Bind to Remote Data</a></h3>

<p><strong>Step 1</strong> Define the ListView via a declarative binding.</p>

<h6>Example</h6>

<pre><code>&lt;div data-role="view" data-init="viewInit"&gt;
     &lt;header data-role="header"&gt;
         &lt;div data-role="navbar"&gt;My App&lt;/div&gt;
     &lt;/header&gt;

     &lt;ul id="remoteListView" data-source="dataSource" data-role="listview" data-template="template" data-endless-scroll="true"&gt;&lt;/ul&gt;
&lt;/div&gt;

&lt;script id="template" type="text/x-kendo-template"&gt;
    #: ProductName #
&lt;/script&gt;
</code></pre>

<p><strong>Step 2</strong> Define a DataSource instance that will fetch the data from the Northwind oData service.</p>

<h6>Example</h6>

<pre><code>var dataSource = new kendo.data.DataSource({
  type: "odata",
  transport: {
    read: {
      url: "https://demos.telerik.com/kendo-ui/service/Northwind.svc/Products"
    }
  },
  schema: {
    total: "d.__count" // schema total is required for the server paging to work as expected
  },
  sort: {
    field: "ProductID",
    dir: "desc"
  },
  serverPaging: true,
  serverSorting: true,
  pageSize: 50
});
</code></pre>

<!--__-->

<p>This is the live example of the representation above:</p>

<pre data-lang="html"><code>&lt;div data-role="view" data-init="viewInit"&gt;
  &lt;header data-role="header"&gt;
    &lt;div data-role="navbar"&gt;My App&lt;/div&gt;
  &lt;/header&gt;

  &lt;ul id="remoteListView" data-source="dataSource" data-role="listview" data-template="template" data-endless-scroll="true"&gt;&lt;/ul&gt;
&lt;/div&gt;

&lt;script id="template" type="text/x-kendo-template"&gt;
#: ProductName #
&lt;/script&gt;

&lt;section data-role="layout" data-id="default"&gt;

&lt;/section&gt;

&lt;script&gt;
  var dataSource = new kendo.data.DataSource({
    type: "odata",
    transport: {
      read: {
        url: "https://demos.telerik.com/kendo-ui/service/Northwind.svc/Products"
      }
    },
    schema: {
      total: "d.__count"
    },
    sort: {
      field: "ProductID",
      dir: "desc"
    },
    serverPaging: true,
    serverSorting: true,
    pageSize: 50
  });

  var app = new kendo.mobile.Application(document.body);
&lt;/script&gt;
</code></pre>

<h2 id="see-also"><a href="#see-also">See Also</a></h2>

<p>Other articles and how-to examples on the Hybrid UI ListView:</p>

<ul>
<li><a href="/api/javascript/mobile/ui/listview">Hybrid UI ListView JavaScript API Reference</a></li>
<li><a href="/controls/hybrid/listview/overview">Overview of the Hybrid UI ListView</a></li>
<li><a href="/controls/hybrid/listview/pull-to-refresh">Pull-to-Refresh Feature</a></li>
</ul>

<p>For how-to examples on the Kendo UI hybrid ListView, browse its <a href="/controls/hybrid/listview/how-to/group-data"><strong>How To</strong> documentation folder</a>.</p> 
        </article>
    </div>
    <div id="feedback-container">
  <div id="feedback-section">
    <script src="/assets/feedback.js?cb=e99a3802c754fe2425831d58312c7c8b"></script>
    <span id="popupNotification"></span>
    <div id="feedback-menu-container">
      <div id="helpful-buttons-container">
        <span class="side-title">Is this article helpful?</span>
        <a class="button" id="yesButton">Yes</a> /
        <a class="button" id="noButton">No</a>
      </div>
      <div id="feedback-submitted-container">
        <span class="side-title">Thank you for your feedback!</span>
      </div>
    </div>
    <div id="feedback-window-container">
      <div id="feedback-form-window" style="background-color: white;">
        <h1 class="feedback-extw__title">Give article feedback</h1>
        <p>Tell us how we can improve this article</p>
        <span id="feedback-form-popup-container"></span>
        <form id="feedback-form">
          <div id="feedback-checkbox-area">
            <input id="hidden-sheet-id" type="hidden" value="14zzclhdh7dMLpg0iq4-2hweCdEiuxxqP3tHdr42-_Cs">
            <label>
              <input type="checkbox" data-bind="checked: outdatedSample" /> Code samples are inaccurate / outdated.
            </label>
            <span class="required-field" data-bind="visible: outdatedSample"></span>
            <textarea id="feedback-code-sample-text-input" placeholder="Please, specify more details ..." class="feedback-extw__textarea"
              data-bind="visible: outdatedSample, value: inaccurateOutdatedCodeSamplesText">
          </textarea>
            <label>
              <input type="checkbox" data-bind="checked: otherMoreInformation" /> I expected to find other / more information.
            </label>
            <span class="required-field" data-bind="visible: otherMoreInformation"></span>
            <textarea id="feedback-more-information-text-input" class="feedback-extw__textarea" placeholder="Please, specify what information can be added ..."
              data-bind="visible: otherMoreInformation, value: otherMoreInformationText">
          </textarea>
            <label>
              <input type="checkbox" data-bind="checked: textErrors" /> There are typos / broken links / broken page elements.
            </label>
            <span class="required-field" data-bind="visible: textErrors"></span>
            <textarea id="feedback-text-errors-text-input" class="feedback-extw__textarea" placeholder="Please, specify what needs to be fixed ..."
              data-bind="visible: textErrors, value: typosLinksElementsText">
          </textarea>
            <label>
              <input type="checkbox" data-bind="checked: inaccurateContent" /> Content is inaccurate / outdated.
            </label>
            <span class="required-field" data-bind="visible: inaccurateContent"></span>
            <textarea id="feedback-inaccurate-content-text-input" class="feedback-extw__textarea" placeholder="Please, specify which conent ..."
              data-bind="visible: inaccurateContent, value: inaccurateOutdatedContentText"></textarea>
            <label>
              <input type="checkbox" data-bind="checked: otherFeedback" /> Other
            </label>
            <span class="required-field" data-bind="visible: otherFeedback"></span>
            <textarea id="feedback-other-text-input" placeholder="Please, enter more details or not listed feedback ..." class="feedback-extw__textarea"
              data-bind="visible: otherFeedback, value: textFeedback">
          </textarea>
            <input id="feedback-email-input" type="email" placeholder="email (optional)" data-email-msg="Email format is not valid."
              class="feedback-extw__input input" data-bind="value: email" />
          </div>
        </form>
        <div class="feedback-extw__foot">
          <button id="form-submit-button" class="feedback-extw__button button button--action">Send feedback</button>
          <button id="form-close-button" class="feedback-extw__button button">Cancel</button>
        </div>
      </div>
    </div>
    <a id="close-button" class="button">
      <img src="/images/close-btn.svg" alt="close" />
    </a>
  </div>
  <div id="feedback-section-dummy">Dummy</div>
</div>
    <footer>
    <p>Copyright &copy; 2017 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.</p>
</footer>

</div>
    </body>
</html>

